How to build your own “Doordash” app
A practical, (relatively) easy-to-do tutorial for developing an event-driven, distributed food delivery app, just like “Doordash”.
Many thanks to Dhanush Kamath for the use case and supporting article.
Meet Fastmart — The fastest and most reliable food delivery app ever built.
The stack we will use -
- MongoDB for orders persistency.
- Node.js as our primary dev-lang.
- Memphis as the used message broker.
- Kubernetes to host our microservices.
High-Level Plan
Let’s start!
1. Sign up to Memphis.dev Cloud
Please head to Memphis.dev Cloud Signup, and create a free acount.
2. Clone the Fastmart repo
git clone https://github.com/yanivbh1/FastMart.git
3. Review the System Architecture, Code, and Flow
Follow the numbers to understand the flow.
FastMart has three main components:
order-service
- Exposes REST endpoints that allow clients to fetch the food menu, place an order and track the order in real-time.
A new order will be saved in mongo with the status “Pending” and will be produced (Pushed) into the “orders” station
GET: /<orderId>
Example: curl http://order-service:3000/30POST: /<order_details>
Example: curl -X POST http://order-service:3000/api/orders -d ‘{“items”:[{“name”:”burger”,”quantity”:1}], “email”:”test@test.com”}’ -H ‘Content-Type: application/json’
The code responsible for communicating with Memphis will be found on -
./order-service/src/services/mqService.js
email-service
- Responsible for notifying the client of the different stages.
email-service consumer messages from two stations: orders
and notifications.
As soon as an order is inserted into the station, the email service notifies the client with an order confirmation.
At the same time listens for new notification requests of other services
resturant-service
- Responsible for fulfilling an order.
- Consume an order
- Process the order
- Change order status at the MongoDB level to “Accepted”
- Using constant sleep time to mimic the preparation of the food by the restaurant
- Change order status at the MongoDB level to “Delivered”
- Sending notifications to the client
4. Deploy “Fastmart” over Kubernetes
Fastmart repo tree -
To deploy the Fastmart namespace and different services,
please run kubectl apply -f k8s-deployment.yaml
kubectl get pods -n fastmart
Output -
Let’s understand why Fastmart services cant start
kubectl logs email-service-5ddb9b58d6-bq2xd -n fastmart
Output -
It appears that the services try to connect to “Memphis” with the user “Fastmart” which does not exist, and we require to create it.
Once the user gets created, the pods will restart automatically and reconnect with Memphis.
5. Order food!
To expose the orders-service
through localhost, run -
kubectl port-forward service/orders 9001:80 --namespace fastmart > /dev/null &
Get the menu
curl localhost:9001/api/menu
Output -
{“items”:[{“name”:”burger”,”price”:50},{“name”:”fries”,”price”:20},{“name”:”coke”,”price”:10}]}
Make an order
curl -X POST localhost:9001/api/orders -d ‘{“items”:[{“name”:”burger”,”quantity”:1}], “email”:”test@gmail.com”}’ -H ‘Content-Type: application/json’
An email should arrive shortly at the email address specified above.
Thanks!